package cn.openea.perpartner.link.filter;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.openea.perpartner.common.auth.config.AuthConfig;
import cn.openea.perpartner.common.auth.entity.LoginBody;
import cn.openea.perpartner.common.auth.entity.R;
import cn.openea.perpartner.common.auth.login.LoginService;
import cn.openea.perpartner.common.auth.path.impl.AntPathMatcher;
import cn.openea.perpartner.common.auth.util.AuthSpUtil;
import cn.openea.perpartner.link.constant.CommonConstants;
import cn.openea.perpartner.link.util.CommonContextHolder;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;

/**
 * @author Weird077
 * @description TODO
 * @date 2023-04-07 14:21
 */
public class SingleSignOnFilter implements Filter {
    private static final AntPathMatcher ANT_PATH_MATCHER = new AntPathMatcher();
    private String ssoUrl;
    private String logoutUrl;
    private String excludedPaths;


    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        ssoUrl = filterConfig.getInitParameter(AuthConfig.SSO_SERVER);
        logoutUrl = filterConfig.getInitParameter(AuthConfig.SSO_LOGOUT_PATH);
        excludedPaths = filterConfig.getInitParameter(AuthConfig.SSO_EXCLUDED_PATHS);
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;
        String servletPath = req.getServletPath();
        //白名单
        if (excludedPaths != null && excludedPaths.trim().length() > 0) {
            for (String excludedPath : StrUtil.split(excludedPaths, ",")) {
                String uriPattern = excludedPath.trim();
                if (ANT_PATH_MATCHER.match(uriPattern, servletPath)) {
                    CommonContextHolder.addValue(CommonConstants.IS_INTERCEPTION, true);
                    chain.doFilter(request, response);
                    CommonContextHolder.remove();
                    return;
                }
            }
        }
        //判断是否logout
        LoginService loginService = AuthSpUtil.getBean(LoginService.class);
        if (StrUtil.isNotBlank(logoutUrl) && logoutUrl.trim().length() > 0 && logoutUrl.equals(servletPath)) {
            loginService.removeSessionIdByCookie(req, res);
            String logoutPageUrl = ssoUrl.concat(AuthConfig.SSO_LOGOUT);
            res.sendRedirect(logoutPageUrl);
            CommonContextHolder.remove();
            return;
        }
        //判断是否登录
        LoginBody user = loginService.loginCheck(req, res);
        if (BeanUtil.isEmpty(user)) {
            if (StrUtil.isNotBlank(req.getHeader("sysid")) || StrUtil.isNotBlank(req.getHeader("syspwd"))) {
                chain.doFilter(request, response);
                CommonContextHolder.remove();
                return;
            }
            String header = req.getHeader("content-type");
            boolean isJson = StrUtil.isNotBlank(header) && header.contains("json");
            if (isJson) {
                res.setContentType("application/json;charset=utf-8");
                res.getWriter().println("{\"code\":" + AuthConfig.SSO_LOGIN_FAIL_RESULT.get(R.CODE_TAG) + ", \"msg\":\"" + AuthConfig.SSO_LOGIN_FAIL_RESULT.get(R.MSG_TAG) + "\"}");
            } else {
                String link = req.getRequestURL().toString();
                String loginPageUrl = ssoUrl.concat(AuthConfig.SSO_LOGIN)
                        + "?" + AuthConfig.REDIRECT_URL + "=" + URLEncoder.encode(link, "UTF-8");
                res.sendRedirect(loginPageUrl);
            }
            return;
        }
        request.setAttribute(AuthConfig.SSO_USER, user);
        chain.doFilter(request, response);
        CommonContextHolder.remove();
    }


}
